package com.zn.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSSClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.netflix.discovery.converters.Auto;
import com.zn.entity.AgencyBusiness;
import com.zn.entity.AppCustomer;
import com.zn.service.AgencyBusinessService;
import com.zn.service.AppCustomerService;
import com.zn.util.*;
import com.zn.vo.Message;
import com.zn.web.dto.AppCustomerDto;
import org.apache.commons.lang.StringUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.springframework.web.multipart.MultipartFile;

/**
 * Created by yinji on 2018/7/9.
 */
@RestController
@RequestMapping("/appCustomer")
public class AppCustomerController {
    private static final Logger LOGGER = LoggerFactory.getLogger(AppCustomerController.class);
    @Value("${aliyun.sms.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.sms.accessKeySecret}")
    private String accessKeySecret;
    @Value("${aliyun.sms.template.open-account-identifying-code}")
    private String OPEN_ACCOUNT_IDENTIFYING_CODE;
    @Value("${aliyun.sms.template.pwd-account-identifying-code}")
    private String PWD_ACCOUNT_IDENTIFYING_CODE;
    @Value("${aliyun.sms.signName}")
    private String signName;
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private AgencyBusinessService agencyBusinessService;
    @Autowired
    private AppCustomerService appCustomerService;
    @Value("${oss.end.point}")
    private  String endPoint;
    @Value("${oss.access.key.id}")
    private  String ossAccessKeyId;
    @Value("${oss.access.key.secret}")
    private  String ossAccessKeySecret;
    @Value("${oss.bucket.name}")
    private  String bucketName;
    @Value("${oss.url}")
    private  String ossUrl;

    /**
     *@描述 注册发送短信验证码 无需校验token
     *@参数  [appCustomerDto]
     *@返回值  org.springframework.http.ResponseEntity<com.zn.vo.Message>
     *@创建人  YinJiaWei
     *@创建时间  15:25
     */
    @RequestMapping(value = "/sendSms",method = RequestMethod.POST)
    public ResponseEntity<Message> sendSms(@RequestBody AppCustomerDto appCustomerDto) {
        try {
            if(StringUtils.isBlank(appCustomerDto.getCustomerTel()) ||
                    StringUtils.isBlank(appCustomerDto.getBusinessInviteCode())){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            //校验注册用户是否存在
            AppCustomer appCustomer=appCustomerService.selectByCustomerTel(appCustomerDto.getCustomerTel());
            if(appCustomer!=null){
                return ResponseEntity.ok(Message.CUSTOMER_EXIST);
            }
            AgencyBusiness isExist=agencyBusinessService.businessInviteCodeIsExist(Integer.valueOf(appCustomerDto.getBusinessInviteCode()));
            //如果代理商邀请码不存在则提示
            if(isExist==null){
                return ResponseEntity.ok(Message.AGENCY_BUSINESS_CODE_IS_NULL);
            }
            LOGGER.info("用户发送验证码的手机号:" + appCustomerDto.getCustomerTel());
            Map map = new HashMap();
            Integer smsCode=UUIDUtils.getMathRandom();
            map.put("code", smsCode);//map里面装有yes
            String jsonObject = JSONObject.toJSONString(map);
            LOGGER.info("验证码:"+jsonObject);
            //将验证码放入到redis中 验证码五分钟内有效
            redisTemplate.opsForValue().set(Constant.SMS_BEFROM + appCustomerDto.getCustomerTel(), smsCode.toString(),300, TimeUnit.SECONDS);
            SendSmsResponse sendSmsResponse= SmsUtils.sendSms(accessKeyId,accessKeySecret,appCustomerDto.getCustomerTel(),OPEN_ACCOUNT_IDENTIFYING_CODE,jsonObject,signName);
            LOGGER.info("sendSmsResponse:"+sendSmsResponse.getMessage());
            if("OK".equals(sendSmsResponse.getCode())){
                return ResponseEntity.ok(Message.REQ_SUCCESS);
            }else if("isv.BUSINESS_LIMIT_CONTROL".equals(sendSmsResponse.getCode())){
                redisTemplate.delete(Constant.SMS_BEFROM + appCustomerDto.getCustomerTel());
                //短信发送过于频繁
                return ResponseEntity.ok(Message.SMS_ALL_TOO_OFTEN);
            }else{
                redisTemplate.delete(Constant.SMS_BEFROM + appCustomerDto.getCustomerTel());
                return ResponseEntity.ok(Message.SMS_SEND_ERROR);
            }
        } catch (Exception e) {
            LOGGER.error("短信验证码发送异常..........",e);
            redisTemplate.delete(Constant.SMS_BEFROM + appCustomerDto.getCustomerTel());
            e.printStackTrace();
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 重置密码发送短信验证码 需要校验token
     * @return
     */
    @RequestMapping(value = "/resetPwdSendSms",method = RequestMethod.POST)
    public ResponseEntity<Message> resetPwdSendSms(@RequestBody AppCustomerDto appCustomerDto) {
        try {
            if(StringUtils.isBlank(appCustomerDto.getCustomerTel())){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            AppCustomer appCustomer=appCustomerService.selectByCustomerTel(appCustomerDto.getCustomerTel());
            if(appCustomer==null){
                //改手机号未注册
                return ResponseEntity.ok(Message.PHONE_NOT_REGISTER);
            }
            LOGGER.info("用户发送验证码的手机号:" + appCustomerDto.getCustomerTel());
            Map map = new HashMap();
            Integer smsCode=UUIDUtils.getMathRandom();
            map.put("code", smsCode);//map里面装有yes
            String jsonObject = JSONObject.toJSONString(map);
            LOGGER.info("验证码:"+jsonObject);
            //将验证码放入到redis中 验证码五分钟内有效
            redisTemplate.opsForValue().set(Constant.RESSET_PWD_BEFROM + appCustomerDto.getCustomerTel(), smsCode.toString(), 300, TimeUnit.SECONDS);
            SendSmsResponse resetPwdSendSmsResponse= SmsUtils.sendSms(accessKeyId,accessKeySecret,appCustomerDto.getCustomerTel(),PWD_ACCOUNT_IDENTIFYING_CODE,jsonObject,signName);
            LOGGER.info("resetPwdSendSmsResponse:"+resetPwdSendSmsResponse.getMessage()+",code:"+resetPwdSendSmsResponse.getCode());
            if("OK".equals(resetPwdSendSmsResponse.getCode())){
                return ResponseEntity.ok(Message.REQ_SUCCESS);
            }else if("isv.BUSINESS_LIMIT_CONTROL".equals(resetPwdSendSmsResponse.getCode())){
                redisTemplate.delete(Constant.RESSET_PWD_BEFROM + appCustomerDto.getCustomerTel());
                //短信发送过于平凡
                return ResponseEntity.ok(Message.SMS_ALL_TOO_OFTEN);
            }else{
                redisTemplate.delete(Constant.RESSET_PWD_BEFROM + appCustomerDto.getCustomerTel());
                return ResponseEntity.ok(Message.SMS_SEND_ERROR);
            }
        } catch (Exception e) {
            redisTemplate.delete(Constant.RESSET_PWD_BEFROM + appCustomerDto.getCustomerTel());
            LOGGER.error("短信验证码发送异常..........",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 找回账户sms
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/retrieveAccountSendSms",method = RequestMethod.POST)
    public ResponseEntity<Message> retrieveAccountSendSms(@RequestBody AppCustomerDto appCustomerDto) {
        try {
            if(StringUtils.isBlank(appCustomerDto.getCustomerTel())){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            AppCustomer appCustomer=appCustomerService.selectByCustomerTel(appCustomerDto.getCustomerTel());
            if(appCustomer==null){
                //改手机号未注册
                return ResponseEntity.ok(Message.PHONE_NOT_REGISTER);
            }
            LOGGER.info("用户发送验证码的手机号:" + appCustomerDto.getCustomerTel());
            Map map = new HashMap();
            Integer smsCode=UUIDUtils.getMathRandom();
            map.put("code", smsCode);//map里面装有yes
            String jsonObject = JSONObject.toJSONString(map);
            LOGGER.info("retrieveAccountSendSms验证码:"+jsonObject);
            //将验证码放入到redis中 验证码五分钟内有效
            redisTemplate.opsForValue().set(Constant.RETRIEVE_ACCOUNT_SMS + appCustomerDto.getCustomerTel(), smsCode.toString(), 300, TimeUnit.SECONDS);
            SendSmsResponse resetPwdSendSmsResponse= SmsUtils.sendSms(accessKeyId,accessKeySecret,appCustomerDto.getCustomerTel(),PWD_ACCOUNT_IDENTIFYING_CODE,jsonObject,signName);
            LOGGER.info("retrieveAccountSendSms:"+resetPwdSendSmsResponse.getMessage()+"，code:"+resetPwdSendSmsResponse.getCode());
            if("OK".equals(resetPwdSendSmsResponse.getCode())){
                return ResponseEntity.ok(Message.REQ_SUCCESS);
            }else if("isv.BUSINESS_LIMIT_CONTROL".equals(resetPwdSendSmsResponse.getCode())){
                redisTemplate.delete(Constant.RETRIEVE_ACCOUNT_SMS + appCustomerDto.getCustomerTel());
                //短信发送过于频繁
                return ResponseEntity.ok(Message.SMS_ALL_TOO_OFTEN);
            }else{
                redisTemplate.delete(Constant.RETRIEVE_ACCOUNT_SMS + appCustomerDto.getCustomerTel());
                return ResponseEntity.ok(Message.SMS_SEND_ERROR);
            }
        } catch (Exception e) {
            redisTemplate.delete(Constant.RETRIEVE_ACCOUNT_SMS + appCustomerDto.getCustomerTel());
            LOGGER.error("短信验证码发送异常..........",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 找回账户
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/retrieveAccount",method = RequestMethod.POST)
    public ResponseEntity<Message> retrieveAccount(@RequestBody AppCustomerDto appCustomerDto) {
        //校验参数
        if(StringUtils.isBlank(appCustomerDto.getCustomerTel()) ||
                StringUtils.isBlank(appCustomerDto.getSmsCode())){
            return ResponseEntity.ok(Message.ARGS_ERROR);
        }
        //校验注册用户是否存在
        AppCustomer appCustomer=appCustomerService.selectByCustomerTel(appCustomerDto.getCustomerTel());
        if(appCustomer==null){
            return ResponseEntity.ok(Message.CUSTOMER_NOT_EXIST);
        }
        //校验验证码是否正确
        String redisSmsCode=redisTemplate.opsForValue().get(Constant.RETRIEVE_ACCOUNT_SMS + appCustomerDto.getCustomerTel());
        //验证码为空
        if(redisSmsCode==null){
            return ResponseEntity.ok(Message.VERIFICATION_CODE_INVALID);
        }
        //校验验证码是否正确
        if(!redisSmsCode.equals(appCustomerDto.getSmsCode())){
            return ResponseEntity.ok(Message.VERIFICATION_CODE_ERROR);
        }
        ResponseEntity<Message> responseEntity=appCustomerService.retrieveAccount(appCustomerDto);
        return responseEntity;
    }

    /**
     * 用户注册接口 无需校验token
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/register",method = RequestMethod.POST)
    public ResponseEntity<Message> register(@RequestBody AppCustomerDto appCustomerDto) {
        try {
            //校验参数
            if(StringUtils.isBlank(appCustomerDto.getCustomerTel()) ||
                    StringUtils.isBlank(appCustomerDto.getBusinessInviteCode()) ||
                    StringUtils.isBlank(appCustomerDto.getSmsCode())||
                    StringUtils.isBlank(appCustomerDto.getCustomerTradePassword()) ||
                    StringUtils.isBlank(appCustomerDto.getAgreementId())){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            /**正则密码交易密码必须6-24位,数字+字母组合**/
            if(!appCustomerDto.getCustomerTradePassword().matches(Constant.TRADE_PASSWORD_REGEX)){
                return ResponseEntity.ok(Message.TRADE_PASSWORD_REGEX_ERROR);
            }
            //校验注册用户是否存在
            AppCustomer appCustomer=appCustomerService.selectByCustomerTel(appCustomerDto.getCustomerTel());
            if(appCustomer!=null){
                return ResponseEntity.ok(Message.CUSTOMER_EXIST);
            }
            AgencyBusiness isExist=agencyBusinessService.businessInviteCodeIsExist(Integer.valueOf(appCustomerDto.getBusinessInviteCode()));
            //如果代理商邀请码不存在则提示
            if(isExist==null){
                return ResponseEntity.ok(Message.AGENCY_BUSINESS_CODE_IS_NULL);
            }
            //校验验证码是否正确
            String redisSmsCode=redisTemplate.opsForValue().get(Constant.SMS_BEFROM + appCustomerDto.getCustomerTel());
            //验证码为空
            if(redisSmsCode==null){
                return ResponseEntity.ok(Message.VERIFICATION_CODE_INVALID);
            }
            //校验验证码是否正确
            if(!redisSmsCode.equals(appCustomerDto.getSmsCode())){
                return ResponseEntity.ok(Message.VERIFICATION_CODE_ERROR);
            }
            appCustomerDto.setBusinessId(isExist.getBusinessId());
            /**做放重复拦截**/
            boolean isRepeat=redisTemplate.opsForValue().setIfAbsent(Constant.PREVENTREPEAT_CUSTOMERTEL+appCustomerDto.getCustomerTel(),"look");
            /**如果没有获取到锁**/
            if(!isRepeat){
                /**返回重复提交异常**/
                return ResponseEntity.ok(Message.REPEAT_SUBMIT_ERROR);
            }
            /**设置失效时长**/
            redisTemplate.expire(Constant.PREVENTREPEAT_CUSTOMERTEL+appCustomerDto.getCustomerTel(),60,TimeUnit.SECONDS);
            ResponseEntity<Message> responseEntity=appCustomerService.customerRegister(appCustomerDto);
            redisTemplate.delete(Constant.PREVENTREPEAT_CUSTOMERTEL+appCustomerDto.getCustomerTel());
            return responseEntity;
        }catch (Exception e){
            LOGGER.error("register...error"+e);
            redisTemplate.delete(Constant.PREVENTREPEAT_CUSTOMERTEL + appCustomerDto.getCustomerTel());
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 用户登录接口 无需校验token
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public ResponseEntity<Message> login(@RequestBody AppCustomerDto appCustomerDto) {
        //校验参数
        if(StringUtils.isBlank(appCustomerDto.getCustomerTradeAccount()) ||
                StringUtils.isBlank(appCustomerDto.getCustomerTradePassword())){
            return ResponseEntity.ok(Message.ARGS_ERROR);
        }
        ResponseEntity<Message> responseEntity=appCustomerService.customerLogin(appCustomerDto);
        return responseEntity;
    }

    /**
     * 用户退出接口 需要校验token
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/loginOut",method = RequestMethod.POST)
    public ResponseEntity<Message> loginOut(@RequestBody AppCustomerDto appCustomerDto) {
        //校验参数
        if(StringUtils.isBlank(appCustomerDto.getCustomerTel())){
            return ResponseEntity.ok(Message.ARGS_ERROR);
        }
        try{
            redisTemplate.delete(Constant.CUSTOMER_TOKEN_BEFROM + appCustomerDto.getCustomerTel());
            return ResponseEntity.ok(Message.REQ_SUCCESS);
        }catch (Exception e){
            LOGGER.error("loginOut.......",e);
            return ResponseEntity.ok(Message.LOGIN_OUT_ERROR);
        }
    }
    /**
     * 用户修改密码接口
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/updatePassword",method = RequestMethod.POST)
    public ResponseEntity<Message> updatePassword(@RequestBody AppCustomerDto appCustomerDto) {
        try{
            ResponseEntity responseEntity=appCustomerService.updateCustomerPassword(appCustomerDto);
            return responseEntity;
        }catch (Exception e){
            LOGGER.error("updatePassword.......",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }
    /**
     * 用户重置密码接口
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/resetPassword",method = RequestMethod.POST)
    public ResponseEntity<Message> ressetPassword(@RequestBody AppCustomerDto appCustomerDto) {
        try{
            //校验参数
            if(StringUtils.isBlank(appCustomerDto.getCustomerTel()) ||
                    StringUtils.isBlank(appCustomerDto.getSmsCode()) ||
                    appCustomerDto.getUpdatePasswordType()==null){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            //校验验证码是否正确
            String redisSmsCode=redisTemplate.opsForValue().get(Constant.RESSET_PWD_BEFROM + appCustomerDto.getCustomerTel());
            //验证码为空
            if(redisSmsCode==null){
                return ResponseEntity.ok(Message.VERIFICATION_CODE_INVALID);
            }
            //校验验证码是否正确
            if(!redisSmsCode.equals(appCustomerDto.getSmsCode())){
                return ResponseEntity.ok(Message.VERIFICATION_CODE_ERROR);
            }
            ResponseEntity responseEntity=appCustomerService.resetCustomerPassword(appCustomerDto);
            return responseEntity;
        }catch (Exception e){
//            e.printStackTrace();
            LOGGER.error("resetPassword.......",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 用户设置资金密码接口
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/initCustomerCapitalPassword",method = RequestMethod.POST)
    public ResponseEntity<Message> initCustomerCapitalPassword(@RequestBody AppCustomerDto appCustomerDto) {
        try{
            if(StringUtils.isBlank(appCustomerDto.getCustomerId()) || StringUtils.isBlank(appCustomerDto.getCustomerCapitalPassword())){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            ResponseEntity responseEntity=appCustomerService.initCustomerCapitalPassword(appCustomerDto);
            return responseEntity;
        }catch (Exception e){
            LOGGER.error("initCustomerCapitalPassword.......",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 获取用户信息
     * @param appCustomerDto
     * @return
     */
    @RequestMapping(value = "/getCustomerInfo",method = RequestMethod.POST)
    public ResponseEntity<Message> getCustomerInfo(@RequestBody AppCustomerDto appCustomerDto) {
        try{
            if(StringUtils.isBlank(appCustomerDto.getCustomerId())){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            AppCustomer appCustomer=appCustomerService.getCustomerInfo(appCustomerDto.getCustomerId());
            return ResponseEntity.ok(Message.successData(appCustomer));
        }catch (Exception e){
            e.printStackTrace();
            LOGGER.error("getCustomerInfo.......",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }

    /**
     * 客户认证接口
     * @param idCardFront
     * @param idCardReverse
     * @param idCard
     * @param name
     * @return
     */
    @RequestMapping(value = "/certification",method =RequestMethod.POST)
    public ResponseEntity<Message> certification(@RequestParam(value = "idCardFront") MultipartFile idCardFront,@RequestParam(value = "idCardReverse") MultipartFile idCardReverse,
                                                 @RequestParam(value = "idCard")String idCard,@RequestParam(value = "name")String name,@RequestParam(value = "customerId")String customerId) {
        Long begin=System.currentTimeMillis();
        LOGGER.info("in mothed .............................");
        try{
            if(idCardFront==null || idCardReverse==null || StringUtils.isBlank(name) || StringUtils.isBlank(idCard) || StringUtils.isBlank(customerId)){
                return ResponseEntity.ok(Message.ARGS_ERROR);
            }
            boolean uploadFlag=true;
            OSSUtil ossUtil=OSSUtil.getInstance(endPoint,ossAccessKeyId,ossAccessKeySecret,bucketName,ossUrl);
            //上传目录 代理商code/Certification
            String imgFolder = "Certification/"+DateUtils.formatDate(new Date());
            OSSClient ossClient = ossUtil.getOSSClient();
            String idCardFrontFileName = System.currentTimeMillis()+"-"+ DateUtils.getDate(new Date())+ "." + idCardFront.getOriginalFilename().substring(idCardFront.getOriginalFilename().lastIndexOf(".") + 1);
            String idCardReverseFileName=System.currentTimeMillis()+"-"+ DateUtils.getDate(new Date())+ "." + idCardReverse.getOriginalFilename().substring(idCardReverse.getOriginalFilename().lastIndexOf(".") + 1);
            //开始上传图片身份证正面
           uploadFlag = ossUtil.uploadInputStreamObject2OSS(ossClient, idCardFront.getInputStream(), idCardFrontFileName, imgFolder);
            //开始上传图片身份证反面
           uploadFlag = ossUtil.uploadInputStreamObject2OSS(ossClient, idCardReverse.getInputStream(), idCardReverseFileName, imgFolder);
//            uploadFlag=true;
            if(!uploadFlag){
                //文件上传异常
                return ResponseEntity.ok(Message.UPLOAD_FILE_ERROR);
            }
            String idCardFrontFilePath=ossUtil.getOssUrl() + "/" + imgFolder + "/" + idCardFrontFileName;
            String idCardReverseFilePath=ossUtil.getOssUrl() + "/" + imgFolder + "/" + idCardReverseFileName;
            /**做放重复拦截**/
            boolean isRepeat=redisTemplate.opsForValue().setIfAbsent(Constant.PREVENTREPEAT_CUSTOMERID+customerId,"look");
            /**如果没有获取到锁**/
            if(!isRepeat){
                /**返回重复提交异常**/
                return ResponseEntity.ok(Message.REPEAT_SUBMIT_ERROR);
            }
            /**设置失效时长**/
            redisTemplate.expire(Constant.PREVENTREPEAT_CUSTOMERID+customerId,60,TimeUnit.SECONDS);
            ResponseEntity responseEntity=appCustomerService.certification(idCardFrontFilePath, idCardReverseFilePath, idCard, name,customerId);
            /**清除KEY**/
            redisTemplate.delete(Constant.PREVENTREPEAT_CUSTOMERID+customerId);
            Long endTime=System.currentTimeMillis();
            LOGGER.info("执行时间："+(endTime-begin));
            return responseEntity;
        }catch (Exception e){
            redisTemplate.delete(Constant.PREVENTREPEAT_CUSTOMERID + customerId);
            LOGGER.error("certification.......",e);
            return ResponseEntity.ok(Message.SYS_ERROR);
        }
    }
}
